package com.infodeli.component.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.infodeli.component.bean.Message;
import com.infodeli.component.config.WebSocketConfig;
import com.infodeli.user.dialog.service.DialogDetailService;
import com.infodeli.user.dialog.service.DialogRelationService;
import com.infodeli.user.login.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Component
@ServerEndpoint("/websocket/dialog/{uid}" /*, configurator = WebSocketConfig.class*/)
public class WebSocketHandler implements ApplicationContextAware {


    //DialogDetailService dialogDetailService;
    // 因为无法通过@Autowired注入，所以只能直接将整个容器通过Aware接口添加进来，再获取需要的组件。
    private static ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
        WebSocketHandler.applicationContext = applicationContext;
    }

    public static Object getBean(String name) {
        return WebSocketHandler.applicationContext.getBean(name);
    }

    private static ObjectMapper objectMapper = new ObjectMapper();
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    private static Map<Long ,Session> map = new ConcurrentHashMap<>();
    private Long uid;

    // 是 PathParam， 不是PathVariable，坑死我了
    @OnOpen
    public void onOpen(@PathParam("uid")Long uid, Session session){
        this.uid = uid;
        map.put(uid, session);
        System.out.println(map.getClass().getName()+"=="+map.hashCode());
        showUserDetail();
    }

    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        // 收到消息，进行解析，并保存到数据库中
        System.out.println("websocket收到消息："+message);
        Message messageBean = objectMapper.readValue(message, Message.class);
        System.out.println(messageBean);
        Session toSession = map.get(messageBean.getRecvUid());

        // 将messageBean的内容存储到数据库中
        DialogDetailService dialogDetailService = (DialogDetailService) getBean("dialogDetailService");
        dialogDetailService.addMessage(messageBean);

        // 发送消息
        if(toSession == null){
            //sendMessage("对方不在线，消息已送达", session);
        }else{
            sendMessage(message, toSession);
        }
    }

    public void sendMessage(String message, Session session) throws IOException {
        System.out.println("websocket发送消息："+message);
        session.getBasicRemote().sendText(message);
    }

    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("websocket产生异常："+error.getMessage());
        error.printStackTrace();
    }

    @OnClose
    public void onClose(Session session){
        map.remove(uid);
        System.out.println("websocket关闭："+uid+"退出");
    }

    private void showUserDetail(){
        System.out.println("存在"+ map.size() +"人："+new ArrayList<>(map.keySet()));
    }
}
